using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Sedna.Core.Scheduler.Conditions;

namespace Sedna.Core.Scheduler
{
    public class Task : BaseCondition, ICondition
    {
        private IRunnable runnable;

        private IList conditions;
        private EventHandler handler;
        private IDictionary<ICondition, int> conditionsState;

        #region Properties

        public IList Conditions
        {
            set { conditions = value; }
        }

        public IRunnable Runnable
        {
            set { runnable = value; }
        }

        #endregion;

        public Task()
        {
            handler = new EventHandler(OnCondition);
            conditionsState = new Dictionary<ICondition, int>();
        }

        protected override void OnEnable()
        {
            foreach (ICondition condition in conditions)
            {
                condition.Trigger += handler;
                //condition.Enabled = true;
                conditionsState[condition] = 0;
            }
        }

        protected override void OnDisable()
        {
            foreach (ICondition condition in conditions)
            {
                condition.Trigger -= handler;
            }
        }

        private void OnCondition(object sender, EventArgs e)
        {
            lock (conditionsState)
            {
                conditionsState[(ICondition)sender]++;
                
                foreach (int count in conditionsState.Values)
                {
                    if (count == 0) return;
                }
            }
            
            Run();
        }

        private void Run()
        {
            lock (conditionsState)
            {
                foreach (ICondition condition in new ArrayList((ICollection)conditionsState.Keys))
                {
                    conditionsState[condition]--;
                }
            }
            
            runnable.Run();
            
            OnTrigger();
        }

    }
}
